home *** CD-ROM | disk | FTP | other *** search
/ CD Actual Thematic 7: Programming / CDAT7.iso / Share / Codigo / hh / rsource.exe / Hexen Source / R_SEGS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-22  |  16.1 KB  |  652 lines

  1.  
  2. //**************************************************************************
  3. //**
  4. //** r_segs.c : Heretic 2 : Raven Software, Corp.
  5. //**
  6. //** $RCSfile: r_segs.c,v $
  7. //** $Revision: 1.4 $
  8. //** $Date: 95/08/28 17:02:44 $
  9. //** $Author: cjr $
  10. //**
  11. //** This version has the tall-sector-crossing-precision-bug fixed.
  12. //**
  13. //**************************************************************************
  14.  
  15. #include "h2def.h"
  16. #include "r_local.h"
  17.  
  18. // OPTIMIZE: closed two sided lines as single sided
  19.  
  20. boolean         segtextured;    // true if any of the segs textures might be vis
  21. boolean         markfloor;              // false if the back side is the same plane
  22. boolean         markceiling;
  23. boolean         maskedtexture;
  24. int                     toptexture, bottomtexture, midtexture;
  25.  
  26.  
  27. angle_t         rw_normalangle;
  28. int                     rw_angle1;              // angle to line origin
  29.  
  30. //
  31. // wall
  32. //
  33. int                     rw_x;
  34. int                     rw_stopx;
  35. angle_t         rw_centerangle;
  36. fixed_t         rw_offset;
  37. fixed_t         rw_distance;
  38. fixed_t         rw_scale;
  39. fixed_t         rw_scalestep;
  40. fixed_t         rw_midtexturemid;
  41. fixed_t         rw_toptexturemid;
  42. fixed_t         rw_bottomtexturemid;
  43.  
  44. int                     worldtop, worldbottom, worldhigh, worldlow;
  45.  
  46. fixed_t         pixhigh, pixlow;
  47. fixed_t         pixhighstep, pixlowstep;
  48. fixed_t         topfrac, topstep;
  49. fixed_t         bottomfrac, bottomstep;
  50.  
  51.  
  52. lighttable_t    **walllights;
  53.  
  54. short           *maskedtexturecol;
  55.  
  56. /*
  57. ================
  58. =
  59. = R_RenderMaskedSegRange
  60. =
  61. ================
  62. */
  63.  
  64. void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
  65. {
  66.     unsigned        index;
  67.     column_t        *col;
  68.     int                     lightnum;
  69.     int                     texnum;
  70.  
  71. //
  72. // calculate light table
  73. // use different light tables for horizontal / vertical / diagonal
  74. // OPTIMIZE: get rid of LIGHTSEGSHIFT globally
  75.     curline = ds->curline;
  76.     frontsector = curline->frontsector;
  77.     backsector = curline->backsector;
  78.     texnum = texturetranslation[curline->sidedef->midtexture];
  79.  
  80.     lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT)+extralight;
  81.     //if (curline->v1->y == curline->v2->y)
  82.     //    lightnum--;
  83.     //else if (curline->v1->x == curline->v2->x)
  84.     //    lightnum++;
  85.     //if (lightnum < 0)
  86.     //    walllights = scalelight[0];
  87.     if (lightnum >= LIGHTLEVELS)
  88.         walllights = scalelight[LIGHTLEVELS-1];
  89.     else
  90.         walllights = scalelight[lightnum];
  91.  
  92.     maskedtexturecol = ds->maskedtexturecol;
  93.  
  94.     rw_scalestep = ds->scalestep;
  95.     spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep;
  96.     mfloorclip = ds->sprbottomclip;
  97.     mceilingclip = ds->sprtopclip;
  98.  
  99. //
  100. // find positioning
  101. //
  102.     if (curline->linedef->flags & ML_DONTPEGBOTTOM)
  103.     {
  104.         dc_texturemid = frontsector->floorheight > backsector->floorheight
  105.         ? frontsector->floorheight : backsector->floorheight;
  106.         dc_texturemid = dc_texturemid + textureheight[texnum] - viewz;
  107.     }
  108.     else
  109.     {
  110.         dc_texturemid =frontsector->ceilingheight<backsector->ceilingheight
  111.         ? frontsector->ceilingheight : backsector->ceilingheight;
  112.         dc_texturemid = dc_texturemid - viewz;
  113.     }
  114.     dc_texturemid += curline->sidedef->rowoffset;
  115.  
  116.     if (fixedcolormap)
  117.         dc_colormap = fixedcolormap;
  118. //
  119. // draw the columns
  120. //
  121.     for (dc_x = x1 ; dc_x <= x2 ; dc_x++)
  122.     {
  123.     // calculate lighting
  124.         if (maskedtexturecol[dc_x] != MAXSHORT)
  125.         {
  126.             if (!fixedcolormap)
  127.             {
  128.                 index = spryscale>>LIGHTSCALESHIFT;
  129.                 if (index >=  MAXLIGHTSCALE )
  130.                     index = MAXLIGHTSCALE-1;
  131.                 dc_colormap = walllights[index];
  132.             }
  133.  
  134.             sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale);
  135.             dc_iscale = 0xffffffffu / (unsigned)spryscale;
  136.  
  137.     //
  138.     // draw the texture
  139.     //
  140.             col = (column_t *)(
  141.                 (byte *)R_GetColumn(texnum,maskedtexturecol[dc_x]) -3);
  142.  
  143.             R_DrawMaskedColumn (col, -1);
  144.             maskedtexturecol[dc_x] = MAXSHORT;
  145.         }
  146.         spryscale += rw_scalestep;
  147.     }
  148.  
  149. }
  150.  
  151. /*
  152. ================
  153. =
  154. = R_RenderSegLoop
  155. =
  156. = Draws zero, one, or two textures (and possibly a masked texture) for walls
  157. = Can draw or mark the starting pixel of floor and ceiling textures
  158. =
  159. = CALLED: CORE LOOPING ROUTINE
  160. ================
  161. */
  162.  
  163. #define HEIGHTBITS      12
  164. #define HEIGHTUNIT      (1<<HEIGHTBITS)
  165.  
  166. void R_RenderSegLoop (void)
  167. {
  168.     angle_t         angle;
  169.     unsigned        index;
  170.     int                     yl, yh, mid;
  171.     fixed_t         texturecolumn;
  172.     int                     top, bottom;
  173.  
  174. //      texturecolumn = 0;                              // shut up compiler warning
  175.  
  176.     for ( ; rw_x < rw_stopx ; rw_x++)
  177.     {
  178. //
  179. // mark floor / ceiling areas
  180. //
  181.         yl = (topfrac+HEIGHTUNIT-1)>>HEIGHTBITS;
  182.         if (yl < ceilingclip[rw_x]+1)
  183.             yl = ceilingclip[rw_x]+1;       // no space above wall
  184.         if (markceiling)
  185.         {
  186.             top = ceilingclip[rw_x]+1;
  187.             bottom = yl-1;
  188.             if (bottom >= floorclip[rw_x])
  189.                 bottom = floorclip[rw_x]-1;
  190.             if (top <= bottom)
  191.             {
  192.                 ceilingplane->top[rw_x] = top;
  193.                 ceilingplane->bottom[rw_x] = bottom;
  194.             }
  195.         }
  196.  
  197.         yh = bottomfrac>>HEIGHTBITS;
  198.         if (yh >= floorclip[rw_x])
  199.             yh = floorclip[rw_x]-1;
  200.         if (markfloor)
  201.         {
  202.             top = yh+1;
  203.             bottom = floorclip[rw_x]-1;
  204.             if (top <= ceilingclip[rw_x])
  205.                 top = ceilingclip[rw_x]+1;
  206.             if (top <= bottom)
  207.             {
  208.                 floorplane->top[rw_x] = top;
  209.                 floorplane->bottom[rw_x] = bottom;
  210.             }
  211.         }
  212.  
  213. //
  214. // texturecolumn and lighting are independent of wall tiers
  215. //
  216.         if (segtextured)
  217.         {
  218.         // calculate texture offset
  219.             angle = (rw_centerangle + xtoviewangle[rw_x])>>ANGLETOFINESHIFT;
  220.             texturecolumn = rw_offset-FixedMul(finetangent[angle],rw_distance);
  221.             texturecolumn >>= FRACBITS;
  222.         // calculate lighting
  223.             index = rw_scale>>LIGHTSCALESHIFT;
  224.             if (index >=  MAXLIGHTSCALE )
  225.                 index = MAXLIGHTSCALE-1;
  226.             dc_colormap = walllights[index];
  227.             dc_x = rw_x;
  228.             dc_iscale = 0xffffffffu / (unsigned)rw_scale;
  229.         }
  230.  
  231. //
  232. // draw the wall tiers
  233. //
  234.         if (midtexture)
  235.         {       // single sided line
  236.             dc_yl = yl;
  237.             dc_yh = yh;
  238.             dc_texturemid = rw_midtexturemid;
  239.             dc_source = R_GetColumn(midtexture,texturecolumn);
  240.             colfunc ();
  241.             ceilingclip[rw_x] = viewheight;
  242.             floorclip[rw_x] = -1;
  243.         }
  244.         else
  245.         {       // two sided line
  246.             if (toptexture)
  247.             {       // top wall
  248.                 mid = pixhigh>>HEIGHTBITS;
  249.                 pixhigh += pixhighstep;
  250.                 if (mid >= floorclip[rw_x])
  251.                     mid = floorclip[rw_x]-1;
  252.                 if (mid >= yl)
  253.                 {
  254.                     dc_yl = yl;
  255.                     dc_yh = mid;
  256.                     dc_texturemid = rw_toptexturemid;
  257.                     dc_source = R_GetColumn(toptexture,texturecolumn);
  258.                     colfunc ();
  259.                     ceilingclip[rw_x] = mid;
  260.                 }
  261.                 else
  262.                     ceilingclip[rw_x] = yl-1;
  263.             }
  264.             else
  265.             {       // no top wall
  266.                 if (markceiling)
  267.                     ceilingclip[rw_x] = yl-1;
  268.             }
  269.  
  270.             if (bottomtexture)
  271.             {       // bottom wall
  272.                 mid = (pixlow+HEIGHTUNIT-1)>>HEIGHTBITS;
  273.                 pixlow += pixlowstep;
  274.                 if (mid <= ceilingclip[rw_x])
  275.                     mid = ceilingclip[rw_x]+1;      // no space above wall
  276.                 if (mid <= yh)
  277.                 {
  278.                     dc_yl = mid;
  279.                     dc_yh = yh;
  280.                     dc_texturemid = rw_bottomtexturemid;
  281.                     dc_source = R_GetColumn(bottomtexture,
  282.                          texturecolumn);
  283.                     colfunc ();
  284.                     floorclip[rw_x] = mid;
  285.                 }
  286.                 else
  287.                     floorclip[rw_x] = yh+1;
  288.             }
  289.             else
  290.             {       // no bottom wall
  291.                 if (markfloor)
  292.                     floorclip[rw_x] = yh+1;
  293.             }
  294.  
  295.             if (maskedtexture)
  296.             {       // save texturecol for backdrawing of masked mid texture
  297.                 maskedtexturecol[rw_x] = texturecolumn;
  298.             }
  299.         }
  300.  
  301.         rw_scale += rw_scalestep;
  302.         topfrac += topstep;
  303.         bottomfrac += bottomstep;
  304.     }
  305.  
  306. }
  307.  
  308.  
  309.  
  310. /*
  311. =====================
  312. =
  313. = R_StoreWallRange
  314. =
  315. = A wall segment will be drawn between start and stop pixels (inclusive)
  316. =
  317. ======================
  318. */
  319.  
  320. void R_StoreWallRange (int start, int stop)
  321. {
  322.     fixed_t         hyp;
  323.     fixed_t         sineval;
  324.     angle_t         distangle, offsetangle;
  325.     fixed_t         vtop;
  326.     int                     lightnum;
  327.  
  328.     if (ds_p == &drawsegs[MAXDRAWSEGS])
  329.         return;         // don't overflow and crash
  330.  
  331. #ifdef RANGECHECK
  332.     if (start >=viewwidth || start > stop)
  333.         I_Error ("Bad R_RenderWallRange: %i to %i", start , stop);
  334. #endif
  335. #ifdef __NeXT__
  336.     RD_DrawLine (curline);
  337. #endif
  338.  
  339.     sidedef = curline->sidedef;
  340.     linedef = curline->linedef;
  341.  
  342. // mark the segment as visible for auto map
  343.     linedef->flags |= ML_MAPPED;
  344.  
  345. //
  346. // calculate rw_distance for scale calculation
  347. //
  348.     rw_normalangle = curline->angle + ANG90;
  349.     offsetangle = abs(rw_normalangle-rw_angle1);
  350.     if (offsetangle > ANG90)
  351.         offsetangle = ANG90;
  352.     distangle = ANG90 - offsetangle;
  353.     hyp = R_PointToDist (curline->v1->x, curline->v1->y);
  354.     sineval = finesine[distangle>>ANGLETOFINESHIFT];
  355.     rw_distance = FixedMul (hyp, sineval);
  356.  
  357.  
  358.     ds_p->x1 = rw_x = start;
  359.     ds_p->x2 = stop;
  360.     ds_p->curline = curline;
  361.     rw_stopx = stop+1;
  362.  
  363. //
  364. // calculate scale at both ends and step
  365. //
  366.     ds_p->scale1 = rw_scale =
  367.         R_ScaleFromGlobalAngle (viewangle + xtoviewangle[start]);
  368.     if (stop > start )
  369.     {
  370.         ds_p->scale2 = R_ScaleFromGlobalAngle (viewangle + xtoviewangle[stop]);
  371.         ds_p->scalestep = rw_scalestep =
  372.             (ds_p->scale2 - rw_scale) / (stop-start);
  373.     }
  374.     else
  375.     {
  376.     //
  377.     // try to fix the stretched line bug
  378.     //
  379. #if 0
  380.         if (rw_distance < FRACUNIT/2)
  381.         {
  382.             fixed_t         trx,try;
  383.             fixed_t         gxt,gyt;
  384.  
  385.             trx = curline->v1->x - viewx;
  386.             try = curline->v1->y - viewy;
  387.  
  388.             gxt = FixedMul(trx,viewcos);
  389.             gyt = -FixedMul(try,viewsin);
  390.             ds_p->scale1 = FixedDiv(projection, gxt-gyt);
  391.         }
  392. #endif
  393.         ds_p->scale2 = ds_p->scale1;
  394.     }
  395.  
  396.  
  397. //
  398. // calculate texture boundaries and decide if floor / ceiling marks
  399. // are needed
  400. //
  401.     worldtop = frontsector->ceilingheight - viewz;
  402.     worldbottom = frontsector->floorheight - viewz;
  403.  
  404.     midtexture = toptexture = bottomtexture = maskedtexture = 0;
  405.     ds_p->maskedtexturecol = NULL;
  406.  
  407.     if (!backsector)
  408.     {
  409. //
  410. // single sided line
  411. //
  412.         midtexture = texturetranslation[sidedef->midtexture];
  413.         // a single sided line is terminal, so it must mark ends
  414.         markfloor = markceiling = true;
  415.         if (linedef->flags & ML_DONTPEGBOTTOM)
  416.         {
  417.             vtop = frontsector->floorheight +
  418.              textureheight[sidedef->midtexture];
  419.             rw_midtexturemid = vtop - viewz;        // bottom of texture at bottom
  420.         }
  421.         else
  422.             rw_midtexturemid = worldtop;            // top of texture at top
  423.         rw_midtexturemid += sidedef->rowoffset;
  424.         ds_p->silhouette = SIL_BOTH;
  425.         ds_p->sprtopclip = screenheightarray;
  426.         ds_p->sprbottomclip = negonearray;
  427.         ds_p->bsilheight = MAXINT;
  428.         ds_p->tsilheight = MININT;
  429.     }
  430.     else
  431.     {
  432. //
  433. // two sided line
  434. //
  435.         ds_p->sprtopclip = ds_p->sprbottomclip = NULL;
  436.         ds_p->silhouette = 0;
  437.         if (frontsector->floorheight > backsector->floorheight)
  438.         {
  439.             ds_p->silhouette = SIL_BOTTOM;
  440.             ds_p->bsilheight = frontsector->floorheight;
  441.         }
  442.         else if (backsector->floorheight > viewz)
  443.         {
  444.             ds_p->silhouette = SIL_BOTTOM;
  445.             ds_p->bsilheight = MAXINT;
  446. //                      ds_p->sprbottomclip = negonearray;
  447.         }
  448.         if (frontsector->ceilingheight < backsector->ceilingheight)
  449.         {
  450.             ds_p->silhouette |= SIL_TOP;
  451.             ds_p->tsilheight = frontsector->ceilingheight;
  452.         }
  453.         else if (backsector->ceilingheight < viewz)
  454.         {
  455.             ds_p->silhouette |= SIL_TOP;
  456.             ds_p->tsilheight = MININT;
  457. //                      ds_p->sprtopclip = screenheightarray;
  458.         }
  459.  
  460.         if (backsector->ceilingheight <= frontsector->floorheight)
  461.         {
  462.             ds_p->sprbottomclip = negonearray;
  463.             ds_p->bsilheight = MAXINT;
  464.             ds_p->silhouette |= SIL_BOTTOM;
  465.         }
  466.         if (backsector->floorheight >= frontsector->ceilingheight)
  467.         {
  468.             ds_p->sprtopclip = screenheightarray;
  469.             ds_p->tsilheight = MININT;
  470.             ds_p->silhouette |= SIL_TOP;
  471.         }
  472.         worldhigh = backsector->ceilingheight - viewz;
  473.         worldlow = backsector->floorheight - viewz;
  474.  
  475.         // hack to allow height changes in outdoor areas
  476.         if (frontsector->ceilingpic == skyflatnum
  477.         && backsector->ceilingpic == skyflatnum)
  478.             worldtop = worldhigh;
  479.  
  480.         if (worldlow != worldbottom
  481.         || backsector->floorpic != frontsector->floorpic
  482.         || backsector->lightlevel != frontsector->lightlevel
  483.         || backsector->special != frontsector->special)
  484.             markfloor = true;
  485.         else
  486.             markfloor = false;                              // same plane on both sides
  487.  
  488.         if (worldhigh != worldtop
  489.         || backsector->ceilingpic != frontsector->ceilingpic
  490.         || backsector->lightlevel != frontsector->lightlevel)
  491.             markceiling = true;
  492.         else
  493.             markceiling = false;                    // same plane on both sides
  494.  
  495.         if (backsector->ceilingheight <= frontsector->floorheight
  496.         || backsector->floorheight >= frontsector->ceilingheight)
  497.             markceiling = markfloor = true;         // closed door
  498.  
  499.         if (worldhigh < worldtop)
  500.         {       // top texture
  501.             toptexture = texturetranslation[sidedef->toptexture];
  502.             if (linedef->flags & ML_DONTPEGTOP)
  503.                 rw_toptexturemid = worldtop;            // top of texture at top
  504.             else
  505.             {
  506.                 vtop = backsector->ceilingheight +
  507.                     textureheight[sidedef->toptexture];
  508.                 rw_toptexturemid = vtop - viewz;        // bottom of texture
  509.             }
  510.         }
  511.         if (worldlow > worldbottom)
  512.         {       // bottom texture
  513.             bottomtexture = texturetranslation[sidedef->bottomtexture];
  514.             if (linedef->flags & ML_DONTPEGBOTTOM )
  515.             {               // bottom of texture at bottom
  516.                 rw_bottomtexturemid = worldtop;// top of texture at top
  517.             }
  518.             else    // top of texture at top
  519.                 rw_bottomtexturemid = worldlow;
  520.         }
  521.         rw_toptexturemid += sidedef->rowoffset;
  522.         rw_bottomtexturemid += sidedef->rowoffset;
  523.  
  524.         //
  525.         // allocate space for masked texture tables
  526.         //
  527.         if (sidedef->midtexture)
  528.         {       // masked midtexture
  529.             maskedtexture = true;
  530.             ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw_x;
  531.             lastopening += rw_stopx - rw_x;
  532.         }
  533.     }
  534.  
  535. //
  536. // calculate rw_offset (only needed for textured lines)
  537. //
  538.     segtextured = midtexture | toptexture | bottomtexture | maskedtexture;
  539.  
  540.     if (segtextured)
  541.     {
  542.         offsetangle = rw_normalangle-rw_angle1;
  543.         if (offsetangle > ANG180)
  544.             offsetangle = -offsetangle;
  545.         if (offsetangle > ANG90)
  546.             offsetangle = ANG90;
  547.         sineval = finesine[offsetangle >>ANGLETOFINESHIFT];
  548.         rw_offset = FixedMul (hyp, sineval);
  549.         if (rw_normalangle-rw_angle1 < ANG180)
  550.             rw_offset = -rw_offset;
  551.         rw_offset += sidedef->textureoffset + curline->offset;
  552.         rw_centerangle = ANG90 + viewangle - rw_normalangle;
  553.  
  554.     //
  555.     // calculate light table
  556.     // use different light tables for horizontal / vertical / diagonal
  557.     // OPTIMIZE: get rid of LIGHTSEGSHIFT globally
  558.         if (!fixedcolormap)
  559.         {
  560.             lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT)+extralight;
  561.             //if (curline->v1->y == curline->v2->y)
  562.             //    lightnum--;
  563.             //else if (curline->v1->x == curline->v2->x)
  564.             //    lightnum++;
  565.             //if (lightnum < 0)
  566.             //    walllights = scalelight[0];
  567.             if (lightnum >= LIGHTLEVELS)
  568.                 walllights = scalelight[LIGHTLEVELS-1];
  569.             else
  570.                 walllights = scalelight[lightnum];
  571.         }
  572.     }
  573.  
  574.  
  575. //
  576. // if a floor / ceiling plane is on the wrong side of the view plane
  577. // it is definately invisible and doesn't need to be marked
  578. //
  579.     if (frontsector->floorheight >= viewz)
  580.         markfloor = false;                              // above view plane
  581.     if (frontsector->ceilingheight <= viewz
  582.     && frontsector->ceilingpic != skyflatnum)
  583.         markceiling = false;                    // below view plane
  584.  
  585. //
  586. // calculate incremental stepping values for texture edges
  587. //
  588.     worldtop >>= 4;
  589.     worldbottom >>= 4;
  590.  
  591.     topstep = -FixedMul (rw_scalestep, worldtop);
  592.     topfrac = (centeryfrac>>4) - FixedMul (worldtop, rw_scale);
  593.  
  594.     bottomstep = -FixedMul (rw_scalestep,worldbottom);
  595.     bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw_scale);
  596.  
  597.     if (backsector)
  598.     {
  599.         worldhigh >>= 4;
  600.         worldlow >>= 4;
  601.  
  602.         if (worldhigh < worldtop)
  603.         {
  604.             pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale);
  605.             pixhighstep = -FixedMul (rw_scalestep,worldhigh);
  606.         }
  607.         if (worldlow > worldbottom)
  608.         {
  609.             pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale);
  610.             pixlowstep = -FixedMul (rw_scalestep,worldlow);
  611.         }
  612.     }
  613.  
  614. //
  615. // render it
  616. //
  617.     if (markceiling)
  618.         ceilingplane = R_CheckPlane (ceilingplane, rw_x, rw_stopx-1);
  619.     if (markfloor)
  620.         floorplane = R_CheckPlane (floorplane, rw_x, rw_stopx-1);
  621.  
  622.     R_RenderSegLoop ();
  623.  
  624. //
  625. // save sprite clipping info
  626. //
  627.     if ( ((ds_p->silhouette & SIL_TOP) || maskedtexture) && !ds_p->sprtopclip)
  628.     {
  629.         memcpy (lastopening, ceilingclip+start, 2*(rw_stopx-start));
  630.         ds_p->sprtopclip = lastopening - start;
  631.         lastopening += rw_stopx - start;
  632.     }
  633.     if ( ((ds_p->silhouette & SIL_BOTTOM) || maskedtexture) && !ds_p->sprbottomclip)
  634.     {
  635.         memcpy (lastopening, floorclip+start, 2*(rw_stopx-start));
  636.         ds_p->sprbottomclip = lastopening - start;
  637.         lastopening += rw_stopx - start;
  638.     }
  639.     if (maskedtexture && !(ds_p->silhouette&SIL_TOP))
  640.     {
  641.         ds_p->silhouette |= SIL_TOP;
  642.         ds_p->tsilheight = MININT;
  643.     }
  644.     if (maskedtexture && !(ds_p->silhouette&SIL_BOTTOM))
  645.     {
  646.         ds_p->silhouette |= SIL_BOTTOM;
  647.         ds_p->bsilheight = MAXINT;
  648.     }
  649.     ds_p++;
  650. }
  651.  
  652.